from flask import Flask
from flask_cors import CORS
from flask_login import LoginManager
import logging
from models import User, init_db
from config import Config
from datetime import timedelta
from routes import main, gesture, user
from auth import auth
from utils.cache import init_cache

# 配置日志系统，设置日志级别为 DEBUG1
# 生产环境建议改为 INFO 或 WARNING 以减少日志量
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)


def create_app():
    """工厂函数：创建并配置 Flask 应用实例"""
    app = Flask(__name__, template_folder='templates')

    # 配置跨域资源共享(CORS)
    # 允许所有域名通过任何路径访问 API
    # 生产环境建议限制 origins 为可信域名列表
    CORS(app, resources={r"/*": {"origins": "*"}})

    # 加载配置类中的环境变量
    app.config.from_object(Config)
    app.secret_key = Config.SECRET_KEY

    # 会话配置
    app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(hours=1)  # 会话有效期
    app.config['SESSION_COOKIE_SECURE'] = False  # 开发环境设置为False
    app.config['SESSION_COOKIE_HTTPONLY'] = True  # 防止XSS攻击
    app.config['REMEMBER_COOKIE_DURATION'] = timedelta(days=7)  # 记住登录状态的时间

    # 初始化数据库连接和模型
    init_db(app)

    # 初始化 Redis 缓存服务
    try:
        init_cache(app)
        logger.info("Redis cache initialized successfully")
    except Exception as e:
        logger.error(f"Failed to initialize Redis cache: {str(e)}")
        # 在生产环境中，建议取消注释以下行，使应用启动失败而非部分功能缺失
        # raise

    # 初始化 Flask-Login 用户认证管理
    login_manager = LoginManager()
    login_manager.init_app(app)
    login_manager.login_view = 'auth.login_route'  # 指定登录视图端点
    login_manager.login_message = '请先登录'  # 未登录访问受保护路由时的提示
    login_manager.login_message_category = 'info'  # 消息类别，用于前端样式
    login_manager.session_protection = 'strong'  # 增强会话保护，检测IP和浏览器变化

    # 用户加载回调函数，Flask-Login 通过ID获取用户对象
    @login_manager.user_loader
    def load_user(user_id):
        return User.query.get(int(user_id))

    # 注册各个功能模块的蓝图
    app.register_blueprint(main)  # 主路由蓝图
    app.register_blueprint(gesture)  # 手势识别相关路由
    app.register_blueprint(user)  # 用户管理路由
    app.register_blueprint(auth)  # 认证授权路由

    return app


# 创建应用实例
app = create_app()

# 开发环境直接运行应用
if __name__ == '__main__':
    app.run(debug=Config.DEBUG, host=Config.HOST, port=Config.PORT)